package com.zhkj.lib.http

import android.util.Log
import androidx.annotation.NonNull
import com.google.gson.JsonParseException
import com.zhkj.lib.R
import com.zhkj.lib.base.BaseApplication
import com.zhkj.lib.base.LoginTokenInvalidEvent
import com.zhkj.lib.utils.AccountManager
import com.zhkj.lib.utils.RxBus
import retrofit2.HttpException
import java.net.ConnectException
import java.net.SocketTimeoutException
import java.net.UnknownHostException
import java.util.concurrent.TimeoutException
import javax.net.ssl.SSLException

open class ResponseSubscribeListener<Response : BaseResponse>(
    private val listener: SubscribeListener<Response>
) {

    open fun onStart() {
        listener.onStart()
    }

    open fun onSuccess(resp: Response) {
        val value = HttpResponse<Response>()
        when (resp.code) {
            1, 10001 -> value.apply {
                status = HttpResponseStatus.Status.SUCCESS
                response = resp
                listener.onSuccess(resp)
            }
            401 -> { // 登录信息失效,重新登录
                AccountManager.clearUserInfo()
                listener.onFailure(HttpResponseException(resp.code ?: 401, resp.msg))
                RxBus.post(LoginTokenInvalidEvent())
            }
            else -> value.apply {
                status = HttpResponseStatus.Status.FAILURE
                val exception = HttpResponseException(resp.code ?: 0, resp.msg)
                this.exception = exception
                listener.onFailure(exception)
            }
        }
    }

    open fun onFailure(@NonNull throwable: Throwable) {
        throwable.printStackTrace()
        val value = HttpResponse<BaseResponse>()
        value.run {
            status = HttpResponseStatus.Status.FAILURE
            val error = handleThrowable(throwable)
            exception = error
            listener.onFailure(error)
        }
    }

    companion object {
        fun handleThrowable(@NonNull throwable: Throwable): HttpResponseException {
            return when (throwable) {
                is ConnectException -> HttpResponseException(
                    HttpResponseException.ERROR.CONNECT.code,
                    BaseApplication.INSTANCE.resources.getString(
                        R.string.connect_error
                    )
                )
                is SSLException -> HttpResponseException(
                    HttpResponseException.ERROR.SSL.code,
                    BaseApplication.INSTANCE.resources.getString(
                        R.string.ssl_error
                    )
                )
                is TimeoutException,
                is SocketTimeoutException -> HttpResponseException(
                    HttpResponseException.ERROR.TIMEOUT.code,
                    BaseApplication.INSTANCE.resources.getString(
                        R.string.timeout_error
                    )
                )
                is UnknownHostException -> HttpResponseException(
                    HttpResponseException.ERROR.HOST.code,
                    BaseApplication.INSTANCE.resources.getString(
                        R.string.host_error
                    )
                )
                is JsonParseException -> HttpResponseException(
                    HttpResponseException.ERROR.PARSE.code,
                    BaseApplication.INSTANCE.resources.getString(
                        R.string.parse_error
                    )
                )
                is HttpException -> {
                    var message: String = BaseApplication.INSTANCE.resources
                        .getString(R.string.net_error)
                    if (throwable.code() == 401) { // 登录信息失效,重新登录
                        AccountManager.clearUserInfo()
                        message = BaseApplication.INSTANCE.resources
                            .getString(R.string.token_invalid)
                        RxBus.post(LoginTokenInvalidEvent())
                    }
                    HttpResponseException(throwable.code(), message)
                }
                else -> HttpResponseException(
                    HttpResponseException.ERROR.UNKNOWN.code,
                    throwable.message
                )
            }
        }
    }
}